using Godot;
using System;
using System.Text.RegularExpressions;
public partial class Player : Sprite2D
{
	private Godot.Collections.Dictionary data;
	private bool[] cardsTag = new bool[12];
	public Card[] handCards = new Card[8];
	public FinalCard[] finalCards = new FinalCard[5];
	public Card[] upCards = new Card[5];
	public Sprite2D[] energys = new Sprite2D[12];
	public int handCardsNum = 0;
	private int energy = 2;
	public int energyUseing = 0;
	private int cardNum = 12;
	public int HP = 4000;
	private Random random;
	[Signal]
	public delegate void handCardCheckSignalEventHandler();
	[Signal]
	public delegate void nextSuceessSignalEventHandler();
	[Signal]
	public delegate void showCardSignalEventHandler(int grade, Card node,int atkTemp,int defTemp);
	[Export]
	public Sprite2D[] environmentBlue { get; set; }
	public override void _Ready()
	{
		random = new Random();
		using FileAccess file = FileAccess.Open("res://data.json", FileAccess.ModeFlags.Read);
		string jsonText = file.GetAsText();
		Json json = new Json();
		Error error = json.Parse(jsonText);
		data = json.Data.AsGodotDictionary();
		Array.Fill(cardsTag, true);
		DrawCard(handCardsNum);
		DrawCard(handCardsNum);
		DrawCard(handCardsNum);
		DrawCard(handCardsNum);
		DrawCard(handCardsNum);
		energyUseing = energy;
		for (int i = 0; i < energyUseing; i++)
		{
			energys[i] = new BlueEnery()
			{
				location = i
			};
			AddChild(energys[i]);
		}

	}

	public void SelfDisappear(int location, Vector2 myPosition)
	{
		for (int i = handCardsNum - 1; i >= location; i--)
		{
			handCards[i].GlobalPosition = handCards[i - 1].GlobalPosition;
			handCards[i].location--;
		}
		if (location < handCardsNum) handCards[location].Position = myPosition;
		handCards[location - 1].QueueFree();
		for (int i = location - 1; i < handCardsNum - 1; i++)
		{
			handCards[i] = handCards[i + 1];
		}
		handCardsNum--;
		EmitSignal(SignalName.nextSuceessSignal);
	}

	public override void _Process(double delta)
	{

	}


	public void useCard(int value, Vector2 myPosition, Area2D a1)
	{
		Match match = Regex.Match(a1.Name, @"\d+$");
		if (match.Success)
		{
			int number = int.Parse(match.Value);
			upCards[number - 6] = handCards[value - 1];
		}
		var grade = handCards[value - 1].grade;
		for (int i = handCardsNum - 1; i > value; i--)
		{
			handCards[i].GlobalPosition = handCards[i - 1].GlobalPosition;
			handCards[i].location--;
		}
		if (value != handCardsNum)
		{
			handCards[value].Position = myPosition;
			handCards[value].location--;
		}
		for (int i = value - 1; i + 1 < handCardsNum; i++)
		{
			handCards[i] = handCards[i + 1];
		}
		handCardsNum--;
		while (grade > 0)
		{
			energyUseing--;
			energys[energyUseing].QueueFree();
			grade--;
		}
	}
	public void removeUpPlayerCard(Card p, int i)
	{
		environmentBlue[i].GetParent().RemoveFromGroup("full");
		environmentBlue[i].GetParent().AddToGroup("empty");
		p.QueueFree();
	}
	public void useMagicSignalHand(Card p1,int grade)
	{
		for (int i = 0; i < 5; i++)
		{
			if (p1 == upCards[i])
			{
				upCards[i] = null;
				removeUpPlayerCard(p1, i);
				break;
			}
		}
	}
	public void useTrapSignalHand(Card p1,int grade)
	{
		for (int i = 0; i < 5; i++)
		{
			if (p1 == upCards[i])
			{
				removeUpPlayerCard(p1, i);
				upCards[i] = null;
				break;
			}
		}
	}
	
	public void SelectCardSignalHander(int grade, Card p1, Card p2)
	{
		for (int t = 0; t < handCardsNum; t++)
		{
			handCards[t].status = 1;
		}
		var attackTemp = p1.atk;
		var defTemp = p1.def;
		for (int i = 0; i < 5; i++)
		{
			if (p1 == upCards[i])
			{
				removeUpPlayerCard(p1, i);
				upCards[i] = null;
				break;
			}
		}

		var w = grade;
		while (w > 0)
		{
			energyUseing--;
			energys[energyUseing].QueueFree();
			w--;
		}
		EmitSignal(SignalName.showCardSignal, grade, p2 , attackTemp, defTemp);
	}
	public void DrawCard(int num)
	{
		var jsonData = data["card"].AsGodotArray();
		var step = random.Next(0, cardNum);
		var t = 0;
		while (!cardsTag[t]) t++;
		while (step > 0)
		{
			t++;
			while (!cardsTag[t]) t++;
			step--;
		}
		var tmp = jsonData[t].AsGodotDictionary();
		getCard(Guid.NewGuid().ToString(), num, tmp["name"].AsString(), tmp["atk"].AsInt32(), tmp["def"].AsInt32(), tmp["grade"].AsInt32(), tmp["attribute"].AsString());
		cardNum--;
		cardsTag[t] = false;
		if (cardNum <= 0)
		{
			cardNum = 12;
			Array.Fill(cardsTag, true);
		}


	}

	public void getCard(string _id, int _location, string _name, int _atk, int _def, int _grade, string _attribute)
	{
		Card card = new Card()
		{
			id = _id,
			location = _location + 1,
			name = _name,
			atk = _atk,
			def = _def,
			grade = _grade,
			attribute = _attribute,
			environmentsBlue = environmentBlue
		};
		card.UseCardSignal += useCard;
		card.SelfDisappearSignal += SelfDisappear;
		card.SelectCardSignal += SelectCardSignalHander;
		AddChild(card);
		handCards[_location] = card;
		handCardsNum++;
	}
	public void finalCardSignHandler(int tag)
	{
		if(tag==0){
			var jsonData = data["card"].AsGodotArray();
			var tmp = jsonData[46].AsGodotDictionary();
			finalCards[1] = new FinalCard()
			{
				id = Guid.NewGuid().ToString(),
				location = 2,
				name = tmp["name"].AsString(),
				atk = tmp["atk"].AsInt32(),
				def = tmp["def"].AsInt32(),
				grade = tmp["grade"].AsInt32(),
				attribute = tmp["attribute"].AsString()
			};
			AddChild(finalCards[1]);		
			finalCards[1].GlobalPosition= environmentBlue[1].GlobalPosition;
			tmp = jsonData[47].AsGodotDictionary();
			finalCards[3] = new FinalCard()
			{
				id = Guid.NewGuid().ToString(),
				location = 4,
				name = tmp["name"].AsString(),
				atk = tmp["atk"].AsInt32(),
				def = tmp["def"].AsInt32(),
				grade = tmp["grade"].AsInt32(),
				attribute = tmp["attribute"].AsString()
			};
			AddChild(finalCards[3]);	
			finalCards[3].GlobalPosition= environmentBlue[3].GlobalPosition;
			tmp = jsonData[48].AsGodotDictionary();
			finalCards[2] = new FinalCard()
			{
				id = Guid.NewGuid().ToString(),
				location = 3,
				name = tmp["name"].AsString(),
				atk = tmp["atk"].AsInt32(),
				def = tmp["def"].AsInt32(),
				grade = tmp["grade"].AsInt32(),
				attribute = tmp["attribute"].AsString()
			};
			AddChild(finalCards[2]);		
			finalCards[2].GlobalPosition= environmentBlue[2].GlobalPosition;
		}
		
	}
	public void endOfRoundSignalHandler(int stages)
	{
		if (stages == 0)
		{
			while (energyUseing > 0)
			{
				energyUseing--;
				energys[energyUseing].QueueFree();
			}
			if (energy < 12) energy++;
			energyUseing = energy;
			for (int i = 0; i < energyUseing; i++)
			{
				energys[i] = new BlueEnery()
				{
					location = i
				};
				AddChild(energys[i]);
			}
			DrawCard(handCardsNum);
			DrawCard(handCardsNum);
			EmitSignal(SignalName.handCardCheckSignal);
		}
		else if (stages == 1)
		{
			for (int t = 0; t < 5; t++)
			{
				if (upCards[t] != null)
				{
					upCards[t].status = 0;
				}
			}
			for (int t = 0; t < handCardsNum; t++)
			{
				handCards[t].status = 0;
			}
		}


	}



}
